from PIL import Image, ImageDraw, ImageFont
import os

def load_image(filepath):
    """加载图像文件."""
    if not isinstance(filepath, str):
        print("文件路径必须是字符串。")
        return None
    if not os.path.exists(filepath):
        print(f"文件 '{filepath}' 不存在。")
        return None
    try:
        return Image.open(filepath)
    except Exception as e:
        print(f"加载图像失败: {e}")
        return None

def convert_to_grayscale(image):
    """转换为灰度图像."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    try:
        return image.convert("L")
    except Exception as e:
        print(f"转换为灰度图像失败: {e}")
        return image

def resize_image(image, width, height):
    """缩放图像."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(width, int) or not isinstance(height, int) or width <= 0 or height <= 0:
        print("宽度和高度必须是正整数。")
        return image
    try:
        return image.resize((width, height))  # 缺省参数 resampling=NEAREST
    except Exception as e:
        print(f"缩放图像失败: {e}")
        return image

def save_image(image, filename, format="PNG"):
    """保存图像."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return
    if not isinstance(filename, str):
        print("文件名必须是字符串。")
        return
    try:
        image.save(filename, format)
        print(f"图像已成功保存为 '{filename}'。")
    except Exception as e:
        print(f"保存图像失败: {e}")

def flip_image(image, method="horizontal"):
    """翻转图像."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if method not in ["horizontal", "vertical"]:
        print("无效的翻转方法，必须是 'horizontal' 或 'vertical'。")
        return image
    try:
        if method == "horizontal":
            return image.transpose(Image.FLIP_LEFT_RIGHT)
        elif method == "vertical":
            return image.transpose(Image.FLIP_TOP_BOTTOM)
    except Exception as e:
        print(f"翻转图像失败: {e}")
        return image

def rotate_image(image, angle):
    """旋转图像."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(angle, (int, float)):
        print("旋转角度必须是数字。")
        return image
    try:
        return image.rotate(-angle)  # 逆时针旋转
    except Exception as e:
        print(f"旋转图像失败: {e}")
        return image

def crop_image(image, box):
    """裁剪图像."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(box, (tuple, list)) or len(box) != 4:
        print("裁剪区域必须是一个包含四个整数的元组或列表 (left, upper, right, lower)。")
        return image
    try:
        return image.crop(box)  # box: (left, upper, right, lower)
    except Exception as e:
        print(f"裁剪图像失败: {e}")
        return image

def add_text_watermark(image, text, font_size=30, color=(0, 0, 0, 128), font="arial.ttf"):
    """添加文本水印."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(text, str):
        print("水印文本必须是字符串。")
        return image
    if not isinstance(font_size, int) or font_size <= 0:
        print("字体大小必须是正整数。")
        return image
    if not isinstance(color, (tuple, list)) or len(color) not in [3, 4]:
        print("颜色必须是一个包含3或4个整数的元组或列表 (RGB或RGBA)。")
        return image
    try:
        draw = ImageDraw.Draw(image)
        width, height = image.size

        # 尝试加载字体
        try:
            font = ImageFont.truetype(font, size=font_size)
        except IOError:
            print(f"字体文件 '{font}' 未找到，使用默认字体。")
            font = ImageFont.load_default()  # 使用默认字体

        # 计算文本大小
        text_width, text_height = draw.textsize(text, font=font)

        # 设置水印位置 (右下角)
        x = width - text_width - 10
        y = height - text_height - 10

        # 添加文本
        draw.text((x, y), text, font=font, fill=color)
        return image
    except Exception as e:
        print(f"添加文本水印失败: {e}")
        return image

def add_image_watermark(image, watermark_path, position=(10, 10), opacity=0.5):
    """添加图像水印."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(watermark_path, str):
        print("水印文件路径必须是字符串。")
        return image
    if not os.path.exists(watermark_path):
        print(f"水印文件 '{watermark_path}' 不存在。")
        return image
    if not isinstance(position, (tuple, list)) or len(position) != 2:
        print("水印位置必须是一个包含两个整数的元组或列表 (x, y)。")
        return image
    if not isinstance(opacity, (int, float)) or opacity < 0 or opacity > 1:
        print("水印透明度必须是0到1之间的数字。")
        return image
    try:
        watermark = Image.open(watermark_path).convert("RGBA")
        watermark = watermark.resize((100, 100))  # 调整水印大小
        watermark = watermark.point(lambda p: p * opacity)  # 设置透明度
        image.paste(watermark, position, watermark)
        return image
    except Exception as e:
        print(f"添加图像水印失败: {e}")
        return image

def adjust_brightness(image, factor):
    """调整图像亮度."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(factor, (int, float)) or factor < 0:
        print("亮度因子必须是非负数。")
        return image
    try:
        from PIL import ImageEnhance
        enhancer = ImageEnhance.Brightness(image)
        return enhancer.enhance(factor)
    except Exception as e:
        print(f"调整亮度失败: {e}")
        return image

def adjust_contrast(image, factor):
    """调整图像对比度."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(factor, (int, float)) or factor < 0:
        print("对比度因子必须是非负数。")
        return image
    try:
        from PIL import ImageEnhance
        enhancer = ImageEnhance.Contrast(image)
        return enhancer.enhance(factor)
    except Exception as e:
        print(f"调整对比度失败: {e}")
        return image

def add_border(image, border_width=10, border_color=(255, 255, 255)):
    """为图像添加边框."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if not isinstance(border_width, int) or border_width <= 0:
        print("边框宽度必须是正整数。")
        return image
    if not isinstance(border_color, (tuple, list)) or len(border_color) not in [3, 4]:
        print("边框颜色必须是一个包含3或4个整数的元组或列表 (RGB或RGBA)。")
        return image
    try:
        from PIL import ImageOps
        return ImageOps.expand(image, border=border_width, fill=border_color)
    except Exception as e:
        print(f"添加边框失败: {e}")
        return image

def apply_filter(image, filter_type):
    """应用滤镜."""
    if not isinstance(image, Image.Image):
        print("输入参数必须是一个PIL图像对象。")
        return image
    if filter_type not in ["blur", "contour", "detail", "edge_enhance", "emboss", "sharpen", "smooth"]:
        print("无效的滤镜类型。")
        return image
    try:
        from PIL import ImageFilter
        filters = {
            "blur": ImageFilter.BLUR,
            "contour": ImageFilter.CONTOUR,
            "detail": ImageFilter.DETAIL,
            "edge_enhance": ImageFilter.EDGE_ENHANCE,
            "emboss": ImageFilter.EMBOSS,
            "sharpen": ImageFilter.SHARPEN,
            "smooth": ImageFilter.SMOOTH,
        }
        return image.filter(filters[filter_type])
    except Exception as e:
        print(f"应用滤镜失败: {e}")
        return image